package com.example.multilevelapprovalback.service.impl;


import com.alibaba.excel.EasyExcel;
import com.example.multilevelapprovalback.listener.TeachingProjectListener;
import com.example.multilevelapprovalback.mapper.TeachProjMapper;
import com.example.multilevelapprovalback.pojo.Result;
import com.example.multilevelapprovalback.pojo.TeachingProject;
import com.example.multilevelapprovalback.pojo.TeachingProjectExcel;
import com.example.multilevelapprovalback.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.Year;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class FileServiceImpl implements FileService {
    @Autowired
    private TeachProjMapper teachProjMapper;
    //拦截的url，虚拟路径
    public String pathPattern = "files";
    //自己设置的目录
    private static final String fileDir = "fileStorage";
    //System.getProperty("user.dir")可以得到当前项目所在的根目录，为绝对路径
    /**
     *
     File.separator 是Java中 java.io.File 类提供的一个静态常量，用于表示文件路径分隔符。在不同的操作系统上，文件路径分隔符是不同的。
     在 Windows 操作系统上，文件路径分隔符是反斜杠 \。
     在 Unix/Linux 操作系统上，文件路径分隔符是正斜杠 /。
     */
    public String filePath = System.getProperty("user.dir") + File.separator + fileDir + File.separator;
    /**
     * 文件上传
     * @param file
     * @return
     */
    @Override
    public List<String> upload(MultipartFile[] file) {
        //首次需要生成目录
        File folder = new File(filePath);
        if(!folder.exists()) {
            folder.mkdirs();
        }
        List<String> filePaths = new ArrayList<>();
        for(MultipartFile multipartFile : file) {
            try {
                //得到上传文件的名字
                String originalFilename = multipartFile.getOriginalFilename();
                //获取上传文件的后缀名
                String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

                //随机生成一个UUID
                UUID uuid = UUID.randomUUID();
                //对文件重新命名 UUID + "." + 文件后缀名
                String fileName = uuid + "." + suffix;
                //上传文件的绝对路径
                String absolutePath = filePath + fileName;
                log.info("绝对路径是： {}",absolutePath);
                //将上传的文件保存到指定路径
                multipartFile.transferTo(new File(absolutePath));
                //文件路径
                String separator = "/";
                String path = separator + pathPattern + separator + fileName;
                log.info(path);
                filePaths.add(path);
            } catch (Exception e) {
                log.info("文件上传错误：",e);
            }
        }
        return filePaths;
    }
    /**
     * 文件下载
     * @param path
     * @return
     */
    @Override
    public void download(String path,HttpServletResponse response) {
        try {
            //取得文件名
            String filename = path.substring(path.lastIndexOf("/") + 1);
            //文件的绝对路径
            String filepath = filePath + filename;
            // filepath是指欲下载的文件的路径。
            File file = new File(filepath);
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件
            InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
            //获取输入流中可读取的字节数，这个方法的返回值并不总是等于文件按的大小，它取决于底层输入流的实现。在这里用于创建一个刚好能容纳整个文件内容的字节数组。
            byte[] buffer = new byte[fis.available()];
            //从输入流中读取字节数据到字节数组中
            fis.read(buffer);
            //关闭输入流，释放资源，确保在使用完后将其关闭
            fis.close();
            // 清空response，以便重新设置
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");  //设置响应的字符编码为 UTF-8
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            //创建一个缓冲输出流
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            //设置响应的内容类型为 application/octet-stream，表示二进制流，适用于任意文件类型。这是为了确保浏览器知道它正在处理二进制数据，而不是尝试解析文件内容
            response.setContentType("application/octet-stream");
            toClient.write(buffer);  //将文件内容写入响应输出流
            toClient.flush();  //刷新输出流，确保所有数据被写入底层输出流。
            toClient.close();  //关闭输出流，释放资源
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    /**
     * 删除文件
     * @param path
     * @return
     */
    @Override
    public boolean delete(String path) {
        String[] pathArray = path.split(",");
        for(String p : pathArray) {
            String fileName = p.substring(p.lastIndexOf("/"));
            String absolutePath = filePath + fileName;
            File file = new File(absolutePath);
            if(file.exists()) {
                if( !file.delete()) return false;
            }
        }
        return true;
    }
}
